#include "StepCont.h"

StepCont_T* StepCont_t;

//************************************
// Method:    	CALCU_SAMA					//< SAMA运算函数
// Programmer:  duan
// Time:		2019/04/23
// Returns:   	bool						//< 成功：true；失败：false
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	float dt					//< 运算周期
// Parameter: 	bool * DI					//< 数字量输入值数组指针
// Parameter: 	bool * DO					//< 数字量输出值数组指针
// Parameter: 	bool * AI					//< 模拟量输入值数组指针
// Parameter: 	bool * AO					//< 模拟量输出值数组指针
//************************************
bool CALCU_SAMA(StepCont)(Model_Base_t* arg, float dt, bool* DI, bool* DO, float* AI, float* AO)
{
#define IPOW(a,j) {/*duan IPOW(a,j)之间不可以有空格 */\
	int iTemp =1;\
	if(j > 32)\
		tmp_int = 0;\
	if(a!=2)\
		tmp_int=(int)(pow(a,j));\
	else{\
		iTemp = iTemp  << j;\
		tmp_int = iTemp;\
		}\
	}

#define StepCur_Pos StepCur_Num[0]-1
	///****************变量定义区开始**************/

	int Step_Ban = 0;
	int i = 0;
	int tmp_int = 0;
	///*<<<<<定义输入变量>>>>>*/
	int Step_Preset;				//< 预置步
	int Bit_Ban;					//< 按位禁止步 当其为1时，禁止或跳过对应的步

	bool Step_Start;				//< 步序逻辑启动信号
	bool Step_Stop;					//< 步序暂停信号
	bool Step_Delay;				//< 步序延时

	bool Step_FB[8];				//< duan 是否对其进行初始化，待定？？？？？？？

	bool Step_Res;					//< 复位，步序逻辑结束
	bool Step_Single;				//< 单步方式，启动时只执行一步
	bool Step_Jump;					//< 跳步，跳过当前步执行下一步

	///*<<<<<定义输出变量>>>>>*/
	float StepCurNum_Out = 0;				//< 当前步序号
	float StepCurRUNTime_Out = 0;			//< 步序执行时间（输出正在执行的步序已经进行的时间）
	float StepCurRSTime_Out = 0;			//< 步序剩余时间（输出正在执行的步序还剩余的时间）

	bool Step_RunSta = 0;			    //< 步序进行状态，步序逻辑正在进行时，输出1
	bool Step_FailSta = 0;				//< 步序暂停状态，当任意步序超时或者被暂停时，输出1
	bool Step_EndSta = 0;				//< 步序完成状态，当步序成功完成设定的最大步序时，输出1

	bool Step_Sta[8] = { 0 };					//< duan 是否对其进行初始化，待定？？？？？？？



	///*<<<<<定义参数变量>>>>>*/
	int Step_Max;					//< 最大步数
	int Step_SetTime[8];
	int Step_LimitT[8];



	///*<<<<<定义中间变量>>>>>*/
	int* Last_Step_Preset;				//< 上一时刻预置步
	int* Last_Bit_Ban;					//< 上一时刻按位禁止步 

	bool* Step_Runing;                //处于正常运行状态
	bool* Step_Stopping;             // 处于停止状态
	bool* Step_Changing;//该变量在以前的程序里未用到，现改为“处于结束状态”
	bool* Step_Failing; //处于失败状态

	int* Init_Count;					//< 初始化标志
	int* StepCur_Num;					//< 当前步序号
	bool* Last_Step_Res;				//< 上一时刻复位
	bool* Last_Step_Start;
	bool* Last_Step_Stop;				//< 上一时刻步序暂停信号
	bool* Last_Step_Jump;				//< 上一时刻跳步

	float* Step_RunTime[8];

	float* StopCurNum_Out;              //暂停时步序号
	float* StopCurRUNTime_Out;           //暂停时步序执行时间

	///****************变量定义区结束**************/

	NAME(StepCont)* Obj = (NAME(StepCont)*)arg;

	///****************变量赋值**************/
	///*<<<<<输入变量赋值>>>>>*/
	Step_Preset = AI[0];			//< 预置步
	Bit_Ban = AI[1];				//< 按位禁止步 当其为1时，禁止或跳过对应的步

	Step_Start = DI[0];				//< 步序逻辑启动信号
	Step_Stop = DI[1];				//< 步序暂停信号
	Step_Delay = DI[2];				//< 步序延时
	Step_FB[0] = DI[3];				//< 第1步完成，动作反馈信号
	Step_FB[1] = DI[4];				//< 第2步完成，动作反馈信号
	Step_FB[2] = DI[5];				//< 第3步完成，动作反馈信号
	Step_FB[3] = DI[6];				//< 第4步完成，动作反馈信号
	Step_FB[4] = DI[7];				//< 第5步完成，动作反馈信号
	Step_FB[5] = DI[8];				//< 第6步完成，动作反馈信号
	Step_FB[6] = DI[9];				//< 第7步完成，动作反馈信号
	Step_FB[7] = DI[10];			//< 第8步完成，动作反馈信号
	Step_Res = DI[11];				//< 复位，步序逻辑结束
	Step_Single = DI[12];			//< 单步方式，启动时只执行一步
	Step_Jump = DI[13];				//< 跳步，跳过当前步执行下一步		

	///*<<<<<参数变量赋值>>>>>*/
	Step_Max = Obj->Par.Step_Max;						//< 最大步数

	for (i = 0; i < 8; i++)
	{
		Step_SetTime[i] = Obj->Par.Step_SetTime[i];
		Step_LimitT[i] = Obj->Par.Step_LimitT[i];
	}


	///*<<<<<中间变量赋值>>>>>*/
	Last_Step_Preset = &(Obj->Sta.Last_Step_Preset);				//< 上一时刻预置步
	Last_Bit_Ban = &(Obj->Sta.Last_Bit_Ban);						//< 上一时刻按位禁止步 

	Step_Runing = &(Obj->Sta.Step_Runing);
	Step_Stopping = &(Obj->Sta.Step_Stopping);
	Step_Changing = &(Obj->Sta.Step_Changing);
	Step_Failing = &(Obj->Sta.Step_Failing);

	Init_Count = &(Obj->Sta.Init_Count);							//< 初始化标志
	StepCur_Num = &(Obj->Sta.StepCur_Num);							//< 当前步序号
	Last_Step_Res = &(Obj->Sta.Last_Step_Res);						//< 上一时刻复位
	Last_Step_Start = &(Obj->Sta.Last_Step_Start);					//< 上一时刻逻辑启动信号
	Last_Step_Stop = &(Obj->Sta.Last_Step_Stop);					//< 上一时刻步序暂停信号
	Last_Step_Jump = &(Obj->Sta.Last_Step_Jump);						//< 上一时刻跳步


	for (i = 0; i < 8; i++)
		Step_RunTime[i] = &(Obj->Sta.Step_RunTime[i]);

	StopCurNum_Out = &(Obj->Sta.StopCurNum_Out);
	StopCurRUNTime_Out = &(Obj->Sta.StopCurRUNTime_Out);
	///**************变量赋值结束************/

	///********************************************/
	///**************算法功能实现开始**************/
	///********************************************/
	if (Step_Preset < 0)
		Step_Preset = 0;
	else if (Step_Preset > Step_Max)
		Step_Preset = Step_Max;

	if (Init_Count[0] == 0)						//< 模块初始化
	{
		if (Step_Preset == 0)
			StepCur_Num[0] = 1;
		else
			StepCur_Num[0] = Step_Preset;
	}
	/******************* 判断是否对应输入引脚出现上升沿，认为按下按钮*************************/
	//< 1-----按下复位
	if (Last_Step_Res[0] == false && Step_Res == true)
	{
		Step_Runing[0] = false;
		Step_Stopping[0] = false;
		Step_Changing[0] = false;
		Step_Failing[0] = false;
		StepCur_Num[0] = 1;

		for (i = 0; i < 8; i++)
			Step_RunTime[i][0] = 0;

		StepCurNum_Out = 0;
		StepCurRUNTime_Out = 0;
		StepCurRSTime_Out = 0;

		Step_RunSta = false;
		Step_FailSta = false;
		Step_EndSta = false;

		for (i = 0; i < 8; i++)
			Step_Sta[i] = false;
	}
	//< 2-----完成初始化后，按下启动按钮
	if (Init_Count[0] != 0 && Last_Step_Start[0] == false && Step_Start == true&& Step_Failing[0]==false)
	{
		Step_Runing[0] = true;
		Step_RunTime[StepCur_Pos][0] = 0;

		Step_RunSta = true;
		Step_FailSta = false;
		Step_EndSta = false;

		if (Step_Delay == false && Step_Stopping[0] == false && (Step_Preset > 0 && Step_Preset < Step_Max))
		{
			for (i = 0; i < 8; i++)
				Step_RunTime[i][0] = 0;

			Step_Sta[StepCur_Pos] = false;			//< 当前步指令无效

			StepCur_Num[0] = Step_Preset;					//< 更新当前步为预置步
			Step_Sta[StepCur_Pos] = true;			//< 当前步指令有效

			Step_Runing[0] = true;
			Step_Changing[0] = false;
		}
		else if (Step_Stopping[0] == true ) {
			StepCur_Num[0] = StopCurNum_Out[0];
			Step_RunTime[StepCur_Pos][0] = StopCurRUNTime_Out[0];
		}

		Step_Stopping[0] = false;
	}


	//判断当处于暂停状态时 
	if (Step_Stopping[0] == true) {
		StepCurNum_Out = StopCurNum_Out[0];
		StepCurRUNTime_Out = StopCurRUNTime_Out[0];
		StepCurRSTime_Out = Step_SetTime[StepCur_Pos] - StopCurRUNTime_Out[0];
		int stopi = StopCurNum_Out[0] - 1;
		Step_Sta[stopi] = true;
		Step_FailSta = true;
	}


	//< 3-----完成初始化后，停止按钮按下
	//if (Init_Count != 0 && Last_Step_Stop[0] == false && Last_Step_Start[0] == true)		//< Shike20201105 改正原来错误条件
	if (Init_Count[0] != 0 && Last_Step_Stop[0] == false && Step_Stop == true)
	{
		Step_Runing[0] = false;
		Step_Stopping[0] = true;

		Step_RunSta = false;
		Step_FailSta = true;
		Step_Sta[StepCur_Pos] = false;

		StopCurNum_Out[0] = StepCur_Num[0];
		StopCurRUNTime_Out[0] = Step_RunTime[StepCur_Pos][0];

		StepCurNum_Out = StepCur_Num[0];
		StepCurRUNTime_Out = Step_RunTime[StepCur_Pos][0];
		StepCurRSTime_Out = Step_SetTime[StepCur_Pos] - Step_RunTime[StepCur_Pos][0];
	}
	////< 4-----跳步按键按下，无步序延时，处于运行、停止或者步序超时状态
	if (Last_Step_Jump[0] == false && Step_Jump == true && Step_Delay == false && (Step_Runing[0] == true || Step_Stopping[0] == true && Step_FailSta == true))
	{
		if (StepCur_Num[0] < Step_Max)					//< 若非最后一步则往后跳一步执行
		{
			Step_Stopping[0] =false;
			Step_Sta[StepCur_Pos] = false;
			StepCur_Num[0] += 1;
			Step_Sta[StepCur_Pos] = true;

			if (Step_FailSta == true)
			{
				Step_Runing[0] == true;
				Step_FailSta = false;
			}

			for (i = 0; i < 8; i++)
				Step_RunTime[i][0] = 0;
		}
		else
		{
			Step_Sta[StepCur_Pos] = false;
			StepCur_Num[0] = 1;

			for (i = 0; i < 8; i++)
				Step_RunTime[i][0] = 0;

			Step_RunSta = false;
			Step_EndSta = true;
			Step_Changing[0] = true;
			Step_Runing[0] = false;
			Step_Stopping[0] = false;
		}

		if (Step_EndSta == false)
		{
			StepCurNum_Out = StepCur_Num[0];
			StepCurRUNTime_Out = Step_RunTime[StepCur_Pos][0];
			StepCurRSTime_Out = Step_SetTime[StepCur_Pos] - Step_RunTime[StepCur_Pos][0];
		}
		else
		{
			StepCurNum_Out = 0;
			StepCurRUNTime_Out = 0;
			StepCurRSTime_Out = 0;
		}
	}
	/******************* 以上判断是否对应输入引脚出现上升沿，认为按下按钮*************************/
	


	IPOW(2, StepCur_Pos);
	Step_Ban = tmp_int & Bit_Ban;

	if (Step_Runing[0] == true && Step_Ban == 0)					//< 运行状态中且该步未被禁止
	{
		Step_RunSta = true;
		Step_Sta[StepCur_Pos] = true;
		Step_RunTime[StepCur_Pos][0] += dt;

		////< 该步完成时间到且无步序延时
		if (Step_RunTime[StepCur_Pos][0] >= Step_SetTime[StepCur_Pos] && Step_Delay == false)
		{
			if (Step_FB[StepCur_Pos] == true)
			{
				Step_Sta[StepCur_Pos] = false;
				Step_RunTime[StepCur_Pos][0] = 0;

				if (StepCur_Num[0] >= Step_Max || Step_Single == true)	//< 若为最后一步或者为单步方式，停止，跳回第一步，不执行
				{
					StepCur_Num[0] = 1;
					for (i = 0; i < 8; i++)
						Step_RunTime[i][0] = 0;

					Step_RunSta = false;
					Step_EndSta = true;
					Step_Changing[0] = true;
					Step_Runing[0] = false;
					Step_Stopping[0] = false;
				}
				else
				{
					StepCur_Num[0] += 1;


					///*Step_Ban = ((int)IPOW(2, ((int)StepCur_Pos)))&Bit_Ban;*/		//< /*按位取出相应步序对应的禁止位*/
					if (Step_Ban == false && Step_FB[StepCur_Pos] == false)
						Step_Sta[StepCur_Pos] = true;
					else
						Step_Sta[StepCur_Pos] = false;
				}
			}
		}

		////< 该步完成时间未到，但是该步完成信号到，且无延时，则跳下一步
		if (Step_RunTime[StepCur_Pos][0] < Step_SetTime[StepCur_Pos] && Step_Delay == false && Step_FB[StepCur_Pos] == true)
		{
			Step_Sta[StepCur_Pos] = false;
			Step_RunTime[StepCur_Pos][0] = 0;
			if (StepCur_Num[0] >= Step_Max || Step_Single == true)		//< 若为最后一步或者为单步方式，停止，跳回第一步，不执行
			{
				StepCur_Num[0] = 1;
				for (i = 0; i < 8; i++)
					Step_RunTime[i][0] = 0;

				Step_RunSta = false;
				Step_EndSta = true;
				Step_Changing[0] = true;
				Step_Runing[0] = false;
				Step_Stopping[0] = false;
			}
			else														//< 否则跳到下一步
			{
				StepCur_Num[0] += 1;

				IPOW(2, StepCur_Pos);
				Step_Ban = tmp_int & Bit_Ban;

				///*Step_Ban = ((int)IPOW(2, ((int)StepCur_Pos)))&Bit_Ban;	*/	//< /*按位取出相应步序对应的禁止位*/
				if (Step_Ban == false && Step_FB[StepCur_Pos] == false)
					Step_Sta[StepCur_Pos] = true;
				else
					Step_Sta[StepCur_Pos] = false;
			}
		}

		////< 若未停止且该步完成信号还未到则输出相应步数、时间
		if (Step_EndSta == false && Step_FB[StepCur_Pos] == false)
		{
			StepCurNum_Out = StepCur_Num[0];
			StepCurRUNTime_Out = Step_RunTime[StepCur_Pos][0];
			StepCurRSTime_Out = Step_SetTime[StepCur_Pos] - Step_RunTime[StepCur_Pos][0];
		}
		else
		{
			StepCurNum_Out = 0;
			StepCurRUNTime_Out = 0;
			StepCurRSTime_Out = 0;
		}

		////< 若时间超过设定时间，且当前步骤还没完成（该步反馈信号未到）则停止该步、置位
		if (Step_RunTime[StepCur_Pos][0] >= Step_LimitT[StepCur_Pos] && Step_FB[StepCur_Pos] == false && Step_LimitT[StepCur_Pos] != 0)
		{
			Step_RunSta = false;
			Step_FailSta = true;
			Step_Sta[StepCur_Pos] = false;

			Step_Runing[0] = false;
			Step_Stopping[0] = false;
			Step_Changing[0] = false;
			Step_Failing[0] = true;
		}
	}
	else if (Step_Runing[0] == true && Step_Ban != 0)			//< 当前步被禁止
	{
		Step_RunTime[StepCur_Pos] = 0;
		Step_Sta[StepCur_Pos] = false;

		////< 若为最后一步，则停止，跳第一步
		if (StepCur_Num[0] > Step_Max)
		{
			StepCur_Num[0] = 1;

			for (i = 0; i < 8; i++)
				Step_RunTime[i][0] = 0;

			Step_RunSta = false;
			Step_EndSta = true;
			Step_Changing[0] = true;
			Step_Runing[0] = false;
			Step_Stopping[0] = false;
		}
		////< 否则跳下一步
		else
		{
			StepCur_Num[0] += 1;

			IPOW(2, StepCur_Pos);
			Step_Ban = tmp_int & Bit_Ban;

			///*Step_Ban = ((int)IPOW(2, ((int)StepCur_Pos)))&Bit_Ban;	*/	//< /*按位取出相应步序对应的禁止位*/
			if (Step_Ban == false && Step_FB[StepCur_Pos] == false)
				Step_Sta[StepCur_Pos] = true;
			else
				Step_Sta[StepCur_Pos] = false;
		}
	}


	if (StepCurRUNTime_Out > Step_SetTime[StepCur_Pos]) {
		if (Step_SetTime[StepCur_Pos] != 0) {
			StepCurRUNTime_Out = Step_SetTime[StepCur_Pos];
		}
		StepCurRSTime_Out = 0;
	}

	//判断所有步执行完毕，使Step_EndSta置1
	if (Step_Changing[0] == true) {
		Step_EndSta = true;
	}
	//判断当前步超过限定时间，故直接故障失败
	if (Step_Failing[0] == true) {
		 Step_RunSta = false;			    
		 Step_FailSta = true;				
		 Step_EndSta = false;				

		 Step_Sta[8] = { 0 };					//< duan 是否对其进行初始化，待定？？？？？？？
	}

	Last_Step_Res[0] = Step_Res;
	Last_Step_Start[0] = Step_Start;
	Last_Step_Stop[0] = Step_Stop;
	Last_Step_Jump[0] = Step_Jump;

	Last_Step_Preset[0] = Step_Preset;
	Last_Bit_Ban[0] = Bit_Ban;

	if (Init_Count[0] == 0)					//< 初始化结束标志
		Init_Count[0] += 1;

	///********************************************/
	///**************算法功能实现结束**************/
	///********************************************/

	///****************运算结果输出**************/
	AO[0] = StepCurNum_Out;
	AO[1] = StepCurRUNTime_Out;
	AO[2] = StepCurRSTime_Out;

	DO[0] = Step_RunSta;
	DO[1] = Step_FailSta;
	DO[2] = Step_EndSta;
	DO[3] = Step_Sta[0];
	DO[4] = Step_Sta[1];
	DO[5] = Step_Sta[2];
	DO[6] = Step_Sta[3];
	DO[7] = Step_Sta[4];
	DO[8] = Step_Sta[5];
	DO[9] = Step_Sta[6];
	DO[10] = Step_Sta[7];

	///**************运算结果输出完毕************/
	return true;
}



//************************************
// Method:    	BCPARA						//< 广播SAMA参数变量函数（无参数需要广播的模块直接将BCPara函数设置为NULL即可）
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	void ** Data				//< 广播SAMA参数的数据包的指针
//************************************
int BC_PARA(StepCont)(Model_Base_t* arg, void** Data)
{
	NAME(StepCont)* Obj = (NAME(StepCont)*)arg;
	BC_PARA_PUBLIC(Obj);
	return 0;
}



//************************************
// Method:    	BAK_STA						//< 备份SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg			//< 指定模块类型链表的指针
// Parameter: 	void ** Data				//< 存放数据包当前指针位置的地址
//************************************
int BAK_STA(StepCont)(Model_Base_t* arg, void** Data)
{
	NAME(StepCont)* Obj = (NAME(StepCont)*)arg;
	BAK_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	ANA_STA						//< 解析备份的SAMA运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							//< 成功：返回解析字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg			//< 模块参数结构体指针
// Parameter: 	void ** Data				//< 存放数据包当前指针位置的地址
//************************************
int ANA_STA(StepCont)(Model_Base_t* arg, void** Data)
{
	NAME(StepCont)* Obj = (NAME(StepCont)*)arg;
	ANA_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	CHANGE_PAR				//< 在线修改模块参数函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int						//< 读取字节长度计数值
// Parameter: 	Model_Base_t* arg		//< 指定模块类型链表的指针
// Parameter: 	void** Data				//< 存放数据包当前指针位置的地址
//************************************
int CHANGE_PAR(StepCont)(Model_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(StepCont)*)arg)->Par, Data[0]);
	return _iLen;
}



//************************************
// Method:    	INIT_STAPAR					//< 初始化模块运算中间参数
// Programmer:  lww
// Time:		2018/11/16
// Parameter: 	Model_Base_t* arg			//< 模块参数结构体指针
//************************************
void INIT_STAPAR(StepCont)(Model_Base_t* arg)
{
	NAME(StepCont)* name = (NAME(StepCont)*)arg;
	///****************初始化中间变量结构体**************/
	memset(&(name->Sta), 0, sizeof(name->Sta));
	///**************初始化中间变量结构体结束************/

	///****************对中间变量结构体的相关参数进行赋值**************/

	///**************对中间变量结构体的相关参数进行赋值结束************/
}
